package com.lyf.common.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.*;
import com.lyf.common.exception.ApiException;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * json字符串与对象转换
 *
 * @author lyf
 */
@Slf4j
public class JacksonUtil {

    public static ObjectMapper objectMapper;
    static {
        objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
        // 空beans抛出异常
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // 序列化忽略新增字段
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 不序列化bean中为null的字段
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 不序列化bean中为空的字段
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
    }
    public static String toJsonStringNoException(Object object) {
        if (objectMapper == null) {
            objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }

        if (object == null) {
            return "";
        }

        try {
            return objectMapper.writeValueAsString(object);
        } catch (Exception e) {
            log.error("json转换错误", e);
            return "";
        }
    }

    public static <T> T toObj(String jsonStr, Class<T> valueType) throws Exception {
        if (objectMapper == null) {
            objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }
        if (null == jsonStr || jsonStr.isEmpty()) {
            throw new Exception("input jsonStr is null/empty");
        }

        try {
            return (T)objectMapper.readValue(jsonStr, valueType);
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }
    /**
     * <p>
     * 对象转JSON字符串
     * </p>
     */
    public static String object2Json(Object obj) {
        String result;
        try {
            result = objectMapper.writeValueAsString(obj);
        } catch (IOException e) {
            log.error("对象转JSON字符串", e);
            throw new ApiException("对象转JSON字符串");
        }
        return result;
    }

    public static Map object2Map(Object obj) {
        String object2Json = object2Json(obj);
        Map<?, ?> result = jsonToMap(object2Json);
        return result;
    }

    /**
     * <p>
     * JSON字符串转Map对象
     * </p>
     */
    public static Map<?, ?> jsonToMap(String json) {
        return json2Object(json, Map.class);
    }

    /**
     * <p>
     * JSON转Object对象
     * </p>
     *
     */
    public static <T> T json2Object(String json, Class<T> cls) {
        T result = null;
        try {

            result = objectMapper.readValue(json, cls);
        } catch (IOException e) {
            log.error("对象转JSON字符串", e);
        }
        return result;
    }
    public static <T> T convertValue(Object content, Class<T> valueType) {
        if (content == null) {
            return null;
        }
        T result = null;
        try {
            result = objectMapper.convertValue(content, valueType);
        } catch (Exception e) {
            log.error("", e);
        }
        return result;
    }
    public static <T> T converterObject(Object srcObject, Class<T> destObjectType) {
        String jsonContent = object2Json(srcObject);
        return json2Object(jsonContent, destObjectType);
    }


    public static <T> List<T> convertJson2List(String jsonStr, Class<T> destObjectType) {
        JavaType javaType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, destObjectType);
        try {
            return objectMapper.readValue(jsonStr, javaType);
        } catch (IOException e) {
            log.error("List对象转JSON字符串", e);
        }
        return null;
    }
    public static JsonNode getTreeNode(String jsonStr, String fieldName)  {
        if (objectMapper == null) {
            objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }

        if (null != jsonStr && !jsonStr.isEmpty()) {
            if (null != fieldName && !fieldName.isEmpty()) {
                try {
                    JsonNode jsonNode = objectMapper.readTree(jsonStr);
                    if (jsonNode.isNull()) {
                        throw new ApiException("parse jsonStr error: no build jsonNode");
                    } else if (!jsonNode.has(fieldName)) {
                        throw new ApiException("parse jsonStr but not find fieldName:" + fieldName);
                    } else {
                        return jsonNode.findValue(fieldName);
                    }
                } catch (Exception var3) {
                    throw new ApiException(var3);
                }
            } else {
                throw new ApiException("input fieldName:" + fieldName + " is null/empty");
            }
        } else {
            throw new ApiException("input jsonStr is null/empty");
        }
    }
}


